#include "../include/chat_service_rpc_client.h"
#include "../include/user_list_manger.h"
#include "../include/statusServer_client_rpc.h"

chat_service_rpc_client_item::chat_service_rpc_client_item(const std::string &ip_port)
{
    _channel=grpc::CreateChannel(ip_port,grpc::InsecureChannelCredentials());
    _stub=message::chatServer::NewStub(_channel);
    
    
}


bool chat_service_rpc_client_item::notify_add_friend_apply(const std::string & from_email, const std::string &to_email, const std::string & varify_text, const std::string &from_name)
{
    grpc::ClientContext context;
    message::reqNotifyAddFriendApply req;
    message::resNotifyAddFriendApply res;
    req.set_from_email(from_email);
    req.set_from_name(from_name);
    req.set_to_email(to_email);
    req.set_varify_text(varify_text);

    grpc::Status sts=_stub->NotifyAddFriendApply(&context,req,&res);
    if(sts.ok()){
        return true;
    }else{
        std::cout<<sts.error_code()<<" : "<<sts.error_message()<<std::endl;
        return false;
    }
    return true;
}


bool chat_service_rpc_client_item::notify_friend_apply_res(const std::string &need_send_tar_email, const std::string &to_email, const bool &apply_res)
{
    grpc::ClientContext context;
    message::reqNotifyFriendApplyRes req;
    message::resNotifyFriendApplyRes res;
    req.set_need_send_tar_email(need_send_tar_email);
    req.set_to_email(to_email);
    req.set_apply_res(apply_res);
    grpc::Status sts=_stub->NotifyFriendApplyRes(&context,req,&res);

    if(sts.ok()){
        return true;
    }else{
        std::cout<<sts.error_code()<<" : "<<sts.error_message()<<std::endl;
        return false;
    }

    return true;
}

bool chat_service_rpc_client_item::notify_chat_text_msg(const std::string &from_email, const std::string &to_email, const int &msg_type, const std::string &msg_id, const std::string &msg_data)
{
    grpc::ClientContext context;
    message::reqNotifyChatTextMsg  req;
    message::resNotifyChatTextMsg res;
    req.set_from_email(from_email);
    req.set_to_email(to_email);
    req.set_msg_type(msg_type);
    req.set_msg_id(msg_id);
    req.set_msg_data(msg_data);

    grpc::Status sts=_stub->notifyChatTextMsg(&context,req,&res);
    if(sts.ok()){
        return res.result();
    }else{
        std::cout<<sts.error_code()<<" : "<<sts.error_message()<<std::endl;
        return false;
    }

    return false;
}
















//------------pool相关------------


std::shared_ptr<chat_service_rpc_client_item> chat_service_rpc_client_pool::add_item(const std::string &ip_port){

    std::shared_ptr<chat_service_rpc_client_item>item=nullptr;
    
    this->spin_mtx.lock();
    
    if(client_pool.count(ip_port)){
        item=client_pool[ip_port];
    }else{
        item=std::make_shared<chat_service_rpc_client_item>(ip_port);
        client_pool.insert(std::make_pair(ip_port,item));
    }
    

    this->spin_mtx.unlock();
    std::cout<<"成功加入一个横向chatServer:"<<ip_port<<std::endl;
    return item;

}


std::shared_ptr<chat_service_rpc_client_item> chat_service_rpc_client_pool::find_and_get_item(const std::string &ip_port)
{
    std::shared_ptr<chat_service_rpc_client_item> tar=nullptr;

    this->spin_mtx.lock();
    if(client_pool.count(ip_port)){
        tar=client_pool[ip_port];
        std::cout<<ip_port<<"的chatServer成功找到"<<std::endl;
    }else{
        std::cout<<ip_port<<"的chatServer没找到"<<std::endl;
        
    }
    this->spin_mtx.unlock();
    

    
    return tar;
}

chat_service_rpc_client_pool::~chat_service_rpc_client_pool(){
    this->client_pool.clear();
}

std::shared_ptr<chat_service_rpc_client_item> chat_service_rpc_client_pool::get_rpc_client_item_through_email(const std::string &email){

    std::shared_ptr<chat_service_rpc_client_item> tar_res=nullptr;
    
    //去从本地缓存的其他chat_server的用户列表去找

    std::string search_ip_port_res=user_list_manger::get_instance()->get_client_server_cache(email);

    if(!search_ip_port_res.empty()){
        //不为空
        tar_res=this->find_and_get_item(search_ip_port_res);
        if(tar_res!=nullptr){
            return tar_res;
        }

    }
    //走到这里，说明没有，那么要去状态服务器中找
    std::string tar_ip_port=statusServer_client_rpc::get_instance()->get_forward_target(email);
    if(tar_ip_port.empty()){
        //如果继续为空，就表示不在线
        return tar_res;
    }else{
        //找到了，去创建对应的rpc然后返回
        if(tar_ip_port==user_list_manger::get_instance()->rpc_service_address){
            std::cout<<"找来找去，找到本服务器？？？？"<<std::endl;
            return tar_res;
        }
        //这里可能会重复添加
        tar_res=this->find_and_get_item(tar_ip_port);
        if(tar_res==nullptr){
            tar_res=this->add_item(tar_ip_port);
        }
        
        //更新缓存
        user_list_manger::get_instance()->update_client_server_cache(email,tar_ip_port);
        return tar_res;
    }
    
}

